package main

import (
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"net/http"
	"strconv"
)

var (
	db *gorm.DB
)

func initMySQL() (err error) {
	dsn := "root:1234@(127.0.0.1:3306)/bubble?charset=utf8mb4&parseTime=True&loc=Local"
	db, err = gorm.Open("mysql", dsn)
	if err != nil {
		return err
	}
	//测试连通性
	return db.DB().Ping()
}

type Todo struct {
	ID     int    `json:"id"`
	Title  string `json:"title"`
	Status bool   `json:"status"`
}
type Rsp1 struct {
	Title string `json:"title"`
}

func main() {
	//创建Mysql数据
	//sql:CREATE DATABASE bubble;
	//连接数据库
	err := initMySQL()
	if err != nil {
		panic(err)
	}
	defer db.Close()
	//模型绑定
	db.AutoMigrate(&Todo{})
	//默认路由
	r := gin.Default()
	//加载静态文件
	r.Static("/static", "dist/static")
	//加载html
	r.LoadHTMLGlob("./dist/templates/*")
	//首页展示
	r.GET("/", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", nil)
	})
	//v1(restful api)
	v1Group := r.Group("v1")
	{
		//查看所有待办事项
		v1Group.GET("/todo", func(c *gin.Context) {
			var todoList []Todo
			if err = db.Find(&todoList).Error; err != nil {
				c.JSON(http.StatusBadRequest, gin.H{"error": err})
			} else {
				c.JSON(http.StatusOK, todoList)
			}

		})
		//添加待办事项
		v1Group.POST("/todo", func(c *gin.Context) {
			//用参数绑定接住json数据
			var todo Todo
			c.ShouldBindJSON(&todo)
			//将本title插入数据库并返回响应
			if err = db.Create(&todo).Error; err != nil {
				c.JSON(http.StatusBadRequest, gin.H{"error": err})
			} else {
				c.JSON(http.StatusOK, todo)
			}

		})
		//删除待办事项，,前端发送的body为空，所以没办法用参数绑定，要通过赋值
		v1Group.DELETE("/todo/:id", func(c *gin.Context) {
			//获取参数
			id, ok := c.Params.Get("id")
			if !ok {
				c.JSON(http.StatusOK, gin.H{"error": "无效id"})
				return
			}
			//定义结构体
			var todo Todo
			if err = db.Where("id=?", id).First(&todo).Error; err != nil {
				c.JSON(http.StatusOK, gin.H{"error": err.Error()})
				return
			}
			//字符串转int再赋值
			todo.ID = func() int {
				a, _ := strconv.Atoi(id)
				return a
			}()
			//删除
			if err = db.Delete(&todo).Error; err != nil {
				c.JSON(http.StatusOK, gin.H{"error": err.Error()})
			} else {
				c.JSON(http.StatusOK, todo)
			}
		})
		//修改待办事项状态,前端发送的body里有json式的status字段
		v1Group.PUT("/todo/:id", func(c *gin.Context) {
			id, ok := c.Params.Get("id")
			if !ok {
				c.JSON(http.StatusBadRequest, gin.H{"error": "无效id"})
			}
			var todo Todo
			if err = db.Where("id=?", id).First(&todo).Error; err != nil {
				c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			}
			c.BindJSON(&todo)
			if err = db.Save(&todo).Error; err != nil {
				c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			} else {
				c.JSON(http.StatusOK, todo)
			}
		})
	}
	//run:8080
	r.Run()
}
